package com.zks.second.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;

import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;

public class EchoServer {

    public static void main(String[] args) throws Exception {
        EchoServer echoServer = new EchoServer();
        echoServer.start();
    }

    /**
    * IdleStateHandler 当连接空闲时间太长 将会出发一个IdleStateEvent 事件，然后你可以通过在你的ChannelInboundHandler 中重写userEvent-Triggered()
     * 方法来处理该IdleStateEvent 事件
    * @author zks
    * @date 2019/10/27 19:48
    * @return void
    */
    public void start() throws Exception {
        final EchoServerHander serverHander = new EchoServerHander();
        EventLoopGroup boss = new NioEventLoopGroup();
        EventLoopGroup worker = new NioEventLoopGroup();


        try{
            ServerBootstrap b=new ServerBootstrap();
            b.group(boss,worker).channel(NioServerSocketChannel.class).
                    localAddress(new InetSocketAddress(8020)).
                    childHandler(new ChannelInitializer<SocketChannel>() {

                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new ChannelInitializer<NioSocketChannel>() {
                            @Override
                            protected void initChannel(NioSocketChannel ch) throws Exception {
                                ch.pipeline().addLast(serverHander);
                            }
                        }).
                                addLast(new IdleStateHandler(0,0,60, TimeUnit.SECONDS)).
                                addLast(new HeaterBeatHandler());
                }
            });
            ChannelFuture sync = b.bind().sync();
            sync.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if(!future.isSuccess()){
                        System.out.println("发送失败");
                        future.cause().printStackTrace();;
                        future.channel().close();
                    }
                }
            });
            sync.channel().closeFuture().sync();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            boss.shutdownGracefully().sync();
            worker.shutdownGracefully().sync();
        }

    }
}
